﻿using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace Wams.Admin
{
    [XmlRoot("wams")]
    public class WamsSettings
    {
        [XmlAttribute("ver")]
        public string Version;
        [XmlArray("certificates")]
        [XmlArrayItem("certificate")]
        public List<WamsCertificate> Certificates = new List<WamsCertificate>();
        [XmlArray("sites")]
        [XmlArrayItem("site")]
        public List<WamsSite> Sites = new List<WamsSite>();

        [XmlArray("modules")]
        [XmlArrayItem("module")]
        public List<WamsModule> Modules = new List<WamsModule>();

        public void SaveSettingsFile(CloudStorageAccount cloudAccount, string containerName)
        {
            CloudBlobClient blobClient = cloudAccount.CreateCloudBlobClient();
            // Retrieve a reference to a container. 
            CloudBlobContainer container = blobClient.GetContainerReference(containerName);

            // Create the container if it doesn't already exist.
            if (!container.CreateIfNotExists())
            {
                CloudBlockBlob resourcesBlob = container.GetBlockBlobReference("wams.xml");
                
                using (Stream newResourcesFileStream = resourcesBlob.OpenWrite())
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(WamsSettings));
                    serializer.Serialize(newResourcesFileStream, this);
                }
            }
        }

        public static WamsSettings Load(CloudStorageAccount cloudAccount, string containerName)
        {
            CloudBlobClient blobClient = cloudAccount.CreateCloudBlobClient();
            // Retrieve a reference to a container. 
            CloudBlobContainer container = blobClient.GetContainerReference(containerName);
            CloudBlockBlob settingsFileBlob = container.GetBlockBlobReference("wams.xml");
            if (!container.Exists() || !settingsFileBlob.Exists()) return null;

            using (MemoryStream ms = new MemoryStream())
            {
                settingsFileBlob.DownloadToStream(ms);
                ms.Seek(0, SeekOrigin.Begin);

                XmlSerializer serializer = new XmlSerializer(typeof(WamsSettings));
                return (WamsSettings)serializer.Deserialize(ms);
            }
        }
    }

    public class WamsCertificate
    {
        [XmlAttribute("password")]
        public string Password;
        [XmlText] 
        public string FileName;
    }

    public class WamsModule
    {
        [XmlAttribute("name")]
        public string Name;
        [XmlAttribute("source")]
        public string Source;
        [XmlAttribute("className")]
        public string ClassName;
    }

    public class WamsSite
    {
        [XmlAttribute("id")] 
        public int Id;
        [XmlAttribute("name")] 
        public string Name;
        [XmlAttribute("source")]
        public string Source;

        [XmlAttribute("url")]
        public string Url;

        [XmlArray("bindings")]
        [XmlArrayItem("binding")]
        public List<WamsSiteBinding> Bindings = new List<WamsSiteBinding>();
        [XmlArray("virtualPaths")]
        [XmlArrayItem(ElementName="virtualDir", Type = typeof(WamsSiteVirtualDir))]
        [XmlArrayItem(ElementName = "virtualApp", Type = typeof(WamsSiteVirtualApp))]
        [XmlArrayItem(Type = typeof(WamsSiteVirtualPath))]
        public List<WamsSiteVirtualPath> VirtualPaths = new List<WamsSiteVirtualPath>();
    }

    public enum IsolationLevel
    {
        Site,
        VirtualApp,
        Full
    }

    public abstract class WamsSiteVirtualPath
    {
        [XmlAttribute("path")]
        public string Path;
        
        [XmlAttribute("source")]
        public string Source;
    }

    [XmlRoot("virtualDir")]
    public class WamsSiteVirtualDir : WamsSiteVirtualPath
    {
    } 

    [XmlRoot("virtualApp")]
    public class WamsSiteVirtualApp : WamsSiteVirtualPath
    {
        [XmlAttribute("appPoolIsolation")]
        public IsolationLevel AppPoolIsolation;
    }


    public enum WamsBindingType
    {
        [XmlEnum("http")]
        Http = 0,
        [XmlEnum("https")]
        Https
    }
    public class WamsSiteBinding
    {
        [XmlText]
        public string BindingInfo;
        [XmlAttribute("type")]
        public WamsBindingType BindingType = WamsBindingType.Http;
        [XmlAttribute("certHash")]
        public string CertificateHash = null;
    }
}
